/*
 * Copyright (C) 2022 KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */

#include "blurhelper.h"
#include <QQmlApplicationEngine>
#include <QWindow>

BlurHelper::BlurHelper(QObject *parent)
    : QObject(parent),
      m_radius(0)
{
}

BlurHelper::~BlurHelper()
{
}

void BlurHelper::updateBlur()
{
    enableBlur();
}

void BlurHelper::setRect(const QRect &rect)
{
    if (m_rect != rect) {
        m_rect = rect;
        Q_EMIT rectChanged();

        enableBlur();
    }
}

void BlurHelper::setRadius(const int &radius)
{
    if (m_radius != radius) {
        m_radius = radius;
        Q_EMIT radiusChanged();

        enableBlur();
    }
}

QObject *BlurHelper::window() const
{
    return m_window;
}

void BlurHelper::setWindow(QObject *window)
{
    if (m_window != window) {
        m_window = window;
        Q_EMIT windowChanged();
        enableBlur();
    }
}

void BlurHelper::enableBlur()
{
    QWindow *window = qobject_cast<QWindow *>(m_window);
    if (window) {
         WId wid = window->winId();
         if (m_rect.isEmpty()) {
             KWindowEffects::enableBlurBehind(wid, true);
         } else {
             KWindowEffects::enableBlurBehind(wid, true, calculateRegion(m_rect, m_radius));
         }
    }
}

QRegion BlurHelper::calculateRegion(QRect rect, int radius)
{
    QRegion region(rect.x(), rect.y(), rect.width(),rect.height(), QRegion::Rectangle);

    // top left
    QRegion round (rect.x(), rect.y(), 2*radius, 2*radius, QRegion::Ellipse);
    QRegion corner(rect.x(), rect.y(), radius, radius, QRegion::Rectangle);
    region = region.subtracted(corner.subtracted(round));

    // top right
    round = QRegion(rect.width()-2*radius+rect.x(), rect.y(), 2*radius, 2*radius, QRegion::Ellipse);
    corner = QRegion(rect.width()-radius+rect.x(), rect.y(), radius, radius, QRegion::Rectangle);
    region = region.subtracted(corner.subtracted(round));

    // bottom right
    round = QRegion(rect.width()-2*radius+rect.x(), rect.height()-2*radius+rect.y(), 2*radius, 2*radius, QRegion::Ellipse);
    corner = QRegion(rect.width()-radius+rect.x(), rect.height()-radius+rect.y(), radius, radius, QRegion::Rectangle);
    region = region.subtracted(corner.subtracted(round));

    // bottom left
    round = QRegion(rect.x(), rect.height()-2*radius+rect.y(), 2*radius, 2*radius, QRegion::Ellipse);
    corner = QRegion(rect.x(), rect.height()-radius+rect.y(), radius, radius, QRegion::Rectangle);
    region = region.subtracted(corner.subtracted(round));

    return  region;
}
